<script lang="ts">
    import mixin from "@/uni_modules/u-tools/mixin/mixin";
    import mpMixin from "@/uni_modules/u-tools/mixin/mpMixin";
    import props from "./props";
    import UText from "@/uni_modules/u-text/components/u-text/u-text.vue";
    import UImage from "@/uni_modules/u-image/components/u-image/u-image.vue";
    import message from "./i18n/index";
    import {useI18n} from "vue-i18n";

    export default {
        name: "u-scroller",
        // 混合
        mixins: [props, mixin, mpMixin],
        // 组件
        components: {UText, UImage},
        // 事件
        emits: [
            "scroll",
            "touchStarts",
            "touchMoving",
            "touchFinish",
            "refresh",
            "scrollUpper",
            "scrollLower",
            "scrollStart",
            "scrollEnd"
        ],
        // 暴露方法
        expose: ["setScrollPosition", "getScrollPosition"],
        // 数据
        data()
        {
            return {
                // 触摸琐
                touchLock: false,
                // 滚动区域容器宽度
                contentWidth: 0,
                // 滚动区域容器高度
                contentHeight: 0,
                // 触摸开始坐标
                touchPosition: 0,
                // 移动距离
                moving: 0,
                // 设置滚动条位置
                scrollPosition: 0,
                // 刷新状态（0.初始  1.松开可刷新  2.刷新中  3.刷新成功  4.刷新失败）
                refreshing: 0,
                // 是否要执行刷新
                perform: false,
                // 滚动状态
                rolling: false,
                // 滚动计时器
                rollingTimer: 0,
                // 当前滚动的值
                scroll: 0,
                // 是否允许下拉刷新，因为在滚动条没有在顶部，也就是scroll值不为0的时候，下拉刷新会显示异常
                allowRefresh: false,
                // 滚动区域样式
                movingStyle: {},
                // 加载区域样式
                loadingStyle: {}
            };
        },
        // 创建完毕
        setup()
        {
            const {t} = useI18n({
                locale: getStorage("language") || uni.getLocale(),
                messages: message
            });

            return {t};
        },
        // 页面挂载
        mounted()
        {
            // 初始化
            this.init();
        },
        // 计算函数
        computed: {
            // 获取加载区域背景颜色
            getLoadingBackgroundColor(): Record<string, any>
            {
                let style: Record<string, string> = {};

                // 判断是否存在自定义背景色
                if (this.loadingBackgroundColor)
                {
                    // 判断是否为渐变
                    if (this.loadingBackgroundColor.includes("gradient"))
                    {
                        style.backgroundImage = this.loadingBackgroundColor;
                    }
                    else
                    {
                        style.backgroundColor = this.loadingBackgroundColor;
                    }
                }

                return style;
            },
            // 获取内容区域的内间距
            getSpacing(): Record<string, string>
            {
                let style: Record<string, string> = {};

                // 判断是否存在自定义内容区域的内间距
                if (this.spacing)
                {
                    if (isString(this.spacing) || isNumber(this.spacing))
                    {
                        style.padding = `${this.$u.unit(this.spacing)}`;
                    }
                    else
                    {
                        style.padding = `${this.$u.unit(this.spacing[0])} ${this.$u.unit(this.spacing[1])} ${this.$u.unit(this.spacing[2])} ${this.$u.unit(this.spacing[3])}`;
                    }
                }

                return style;
            },
            // 获取加载状态
            getRefreshState(): string
            {
                switch (this.refreshing)
                {
                    case 0:
                        return "normal";

                    case 1:
                        return "pull";

                    case 2:
                        return "refresh";

                    case 3:
                        return "finish";

                    case 4:
                        return "fail";

                    default:
                        return "normal";
                }
            },
            // 获取拖拽移动进度样式
            getMovingProgressStyle(): Record<string, any>
            {
                const style: Record<string, any> = {
                    borderColor: `${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor}`
                };

                // 初始、默认、刷新状态
                if ([0, 1, 3].includes(this.refreshing))
                {
                    // 当前进度值
                    const progress = this.moving / this.offset;

                    if (progress >= 0 && progress < 0.25)
                    {
                        style.borderColor = `${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor}`;
                    }
                    else if (progress >= 0.25 && progress < 0.5)
                    {
                        style.borderColor = `${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.activeLoadingIconColor}`;
                    }
                    else if (progress >= 0.5 && progress < 0.75)
                    {
                        style.borderColor = `${this.activeLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.activeLoadingIconColor}`;
                    }
                    else if (progress >= 0.75 && progress < 1)
                    {
                        style.borderColor = `${this.activeLoadingIconColor} ${this.activeLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.activeLoadingIconColor}`;
                    }
                    else if (progress >= 1)
                    {
                        style.borderColor = `${this.activeLoadingIconColor} ${this.activeLoadingIconColor} ${this.activeLoadingIconColor} ${this.activeLoadingIconColor}`;
                    }
                }
                // 失败状态
                else if ([4].includes(this.refreshing))
                {
                    style.borderColor = "rgba(255, 0, 0, 1) rgba(255, 0, 0, 1) rgba(255, 0, 0, 1) rgba(255, 0, 0, 1)";
                }
                // 加载中状态
                else
                {
                    style.borderColor = `${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.inactiveLoadingIconColor} ${this.activeLoadingIconColor}`;
                }

                return style;
            },
            // 获取状态文本
            getMovingText(): string
            {
                switch (this.refreshing)
                {
                    case 0:
                        return this.t("scroll.normal");

                    case 1:
                        return this.t("scroll.pull");

                    case 2:
                        return this.t("scroll.refresh");

                    case 3:
                        return this.t("scroll.finish");

                    case 4:
                        return this.t("scroll.fail");

                    default:
                        return this.t("scroll.normal");
                }
            },
            // 获取页脚状态文本
            getPageFooterText(): string
            {
                switch (this.pageStatus)
                {
                    case "loading":
                        return this.t("scroll.loading");

                    case "noMore":
                        return this.t("scroll.noMore");

                    case "empty":
                        return this.t("scroll.empty");

                    default:
                        return "";
                }
            },
            // 生成bem风格的类名
            bemClass(): string
            {
                return bem("scroller", [
                    this.direction
                ]);
            }
        },
        // 方法
        methods: {
            // 初始化
            init(): void
            {
                this.$nextTick(() =>
                {
                    const contextGeometry = uni.createSelectorQuery().in(this).select(".u-scroller");

                    if (contextGeometry)
                    {
                        contextGeometry.boundingClientRect((res: Record<string, any>) =>
                        {
                            // 获取滚动区域容器宽度
                            this.contentWidth = res.width || 0;

                            // 获取滚动区域容器高度
                            this.contentHeight = res.height || 0;

                        }).exec();
                    }
                });
            },
            // 设置滚动条位置
            setScrollPosition(value: number): void
            {
                this.scrollPosition = value;
            },
            // 获取滚动条位置
            getScrollPosition(): number
            {
                return this.scrollPosition;
            },
            // 滚动事件
            scrollHandler(event: Record<string, any>): void
            {
                // 滚动前事件回调
                if (!this.rolling)
                {
                    // 锁定正在滚动
                    this.rolling = true;

                    // 滚动前事件回调
                    this.$emit("scrollStart", {event});
                }

                // 滚动事件回调
                this.$emit("scroll", {event});

                // 清除定时器
                if (this.rollingTimer)
                {
                    clearTimeout(this.rollingTimer);
                }

                // 设置定时器
                this.rollingTimer = setTimeout(() =>
                {
                    // 解锁正在滚动
                    this.rolling = false;

                    // 清除定时器
                    clearTimeout(this.rollingTimer);

                    // 滚动后事件回调
                    this.$emit("scrollEnd", {event});

                }, 100);

                // 设置当前滚动条卷去的值
                if (this.direction === "vertical")
                {
                    this.scroll = event.detail?.scrollTop ?? 0;
                }
                else
                {
                    this.scroll = event.detail?.scrollLeft ?? 0;
                }

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 触摸开始事件
            touchstartHandler(event: TouchEvent): void
            {
                // 判断琐
                if (this.touchLock || this.perform)
                {
                    return;
                }

                // 立即上锁
                this.touchLock = true;

                if (this.enableRefresh)
                {
                    // 重置是否刷新标识
                    this.perform = false;

                    // 获取触摸开始坐标
                    this.touchPosition = this.direction === "vertical" ? event.changedTouches[0].clientY : event.changedTouches[0].clientX;

                    // 重置移动距离
                    this.moving = 0;

                    // 重置刷新状态
                    this.refreshing = 0;

                    // 设置加载样式
                    this.loadingStyle = {};

                    // 设置移动样式
                    this.movingStyle = {};

                    // 判断是否允许刷新
                    this.allowRefresh = this.scroll <= 0;
                }

                // 触摸开始事件
                this.$emit("touchStarts", {event});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 触摸移动事件
            touchmoveHandler(event: TouchEvent): void
            {
                // 判断琐
                if (!this.touchLock || this.perform)
                {
                    return;
                }

                // 触摸移动
                if (this.enableRefresh)
                {
                    // 当前的坐标点
                    const position = this.direction === "vertical" ? event.changedTouches[0].clientY : event.changedTouches[0].clientX;

                    // 计算移动差值
                    const diffY = position - this.touchPosition;

                    // 如果移动差值是负数，则不处理
                    if (diffY > 0 && this.allowRefresh)
                    {
                        // 计算粘滞力
                        const rate = Math.sin(Math.PI * (100 - this.viscosity) / 100 * (diffY / this.contentHeight));

                        // 计算移动距离
                        this.moving = this.maxPull * rate;

                        // 计算刷新状态
                        this.refreshing = this.moving < this.offset ? 0 : 1;

                        // 设置样式
                        if (this.direction === "vertical")
                        {
                            // 设置加载样式
                            this.loadingStyle = {height: `${this.$u.unit(this.moving)}`};

                            // 设置移动样式
                            this.movingStyle = {transform: `translateY(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                        }
                        else
                        {
                            // 设置加载样式
                            this.loadingStyle = {width: `${this.$u.unit(this.moving)}`};

                            // 设置移动样式
                            this.movingStyle = {transform: `translateX(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                        }
                    }
                    else
                    {
                        // 重置刷新状态
                        this.refreshing = 0;

                        // 一旦移动距离小于0，则立即让允许刷新失效
                        this.allowRefresh = false;

                        // 重置加载样式
                        this.loadingStyle = {};

                        // 重置移动样式
                        this.movingStyle = {};
                    }
                }

                // 触摸移动事件
                this.$emit("touchMoving", {event, refreshing: this.refreshing, moving: this.moving});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 触摸结束事件
            touchendHandler(event: TouchEvent): void
            {
                // 判断琐
                if (!this.touchLock || this.perform)
                {
                    return;
                }

                // 解锁
                this.touchLock = false;

                // 判断是否允许刷新
                if (this.enableRefresh)
                {
                    // 当前的坐标点
                    const position = this.direction === "vertical" ? event.changedTouches[0].clientY : event.changedTouches[0].clientX;

                    // 计算移动差值
                    const diffY = position - this.touchPosition;

                    // 如果移动差值是负数，则不处理
                    if (diffY > 0)
                    {
                        // 是否达到刷新条件
                        if (this.refreshing === 1)
                        {
                            // 刷新标识
                            this.perform = true;

                            // 将当前移动位置设置为偏移量
                            this.moving = this.offset;

                            // 设置样式
                            if (this.direction === "vertical")
                            {
                                // 设置加载样式
                                this.loadingStyle = {height: `${this.$u.unit(this.moving)}`, transition: `height ${this.duration}ms linear`};

                                // 设置移动样式
                                this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateY(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                            }
                            else
                            {
                                // 设置加载样式
                                this.loadingStyle = {width: `${this.$u.unit(this.moving)}`, transition: `width ${this.duration}ms linear`};

                                // 设置移动样式
                                this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateX(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                            }
                        }
                        else
                        {
                            // 根本就没有触发过刷新的准备动作
                            if (this.moving === 0)
                            {
                                // 设置加载样式
                                this.loadingStyle = {};

                                // 设置移动样式
                                this.movingStyle = {};
                            }
                            // 将下拉刷新UI触发后，但是又没有执行刷新
                            else
                            {
                                // 重置移动距离
                                this.moving = 0;

                                // 设置样式
                                if (this.direction === "vertical")
                                {
                                    // 设置加载样式
                                    this.loadingStyle = {height: `${this.$u.unit(this.moving)}`, transition: `height ${this.duration}ms linear`};

                                    // 设置移动样式
                                    this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateY(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                                }
                                else
                                {
                                    // 设置加载样式
                                    this.loadingStyle = {width: `${this.$u.unit(this.moving)}`, transition: `width ${this.duration}ms linear`};

                                    // 设置移动样式
                                    this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateX(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                                }
                            }
                        }
                    }
                    else
                    {
                        // 重置移动距离
                        this.moving = 0;

                        // 重置刷新状态
                        this.refreshing = 0;

                        // 重置加载样式
                        this.loadingStyle = {};

                        // 重置移动样式
                        this.movingStyle = {};
                    }
                }

                // 触摸结束事件
                this.$emit("touchFinish", {event, moving: this.moving});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 滚动到顶部事件
            scrolltoupperHandler(event: TouchEvent): void
            {
                this.$emit("scrollUpper", {event});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 滚动到底部事件
            scrolltolowerHandler(event: TouchEvent): void
            {
                this.$emit("scrollLower", {event});

                // 阻止冒泡
                this.stop && this.stopPropagation(event);

                // 阻止事件默认行为
                this.prevent && this.preventDefault(event);
            },
            // 动画结束事件
            transitionendHandler(): void
            {
                // 是否需要刷新
                if (this.perform)
                {
                    // 设置正在加载状态
                    this.refreshing = 2;

                    // 锁定的加载状态
                    const current = this.refreshing;

                    // 触发刷新事件
                    this.$emit("refresh", {
                        success: () =>
                        {
                            // 防止在回调中既执行了success又执行了fail
                            if (current === this.refreshing)
                            {
                                // 设置刷新成功
                                this.refreshing = 3;

                                // 结束刷新
                                finished();
                            }
                        },
                        fail: () =>
                        {
                            // 防止在回调中既执行了success又执行了fail
                            if (current === this.refreshing)
                            {
                                // 设置刷新成功
                                this.refreshing = 4;

                                // 结束刷新
                                finished();
                            }
                        }
                    });
                }
                else
                {
                    // 重置移动位置
                    this.moving = 0;

                    // 重置开始位置
                    this.touchPosition = 0;

                    // 重置刷新状态
                    this.refreshing = 0;

                    // 重置加载样式
                    this.loadingStyle = {};

                    // 重置移动样式
                    this.movingStyle = {};
                }

                // 结束刷新
                const finished = (): void =>
                {
                    asyncFn(() =>
                    {
                        // 重置刷新标记
                        this.perform = false;

                        // 重置移动位置
                        this.moving = 0;

                        // 设置样式
                        if (this.direction === "vertical")
                        {
                            // 设置加载样式
                            this.loadingStyle = {height: `${this.$u.unit(this.moving)}`, transition: `height ${this.duration}ms linear`};

                            // 设置移动样式
                            this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateY(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                        }
                        else
                        {
                            // 设置加载样式
                            this.loadingStyle = {width: `${this.$u.unit(this.moving)}`, transition: `width ${this.duration}ms linear`};

                            // 设置移动样式
                            this.movingStyle = {transition: `transform ${this.duration}ms linear`, transform: `translateX(${this.$u.unit(this.moving)}) translate3d(0, 0, 0)`};
                        }

                    }, 500);
                };
            }
        }
    };
</script>

<template>
    <!-- 滚动组件 -->
    <view
        :class="[
            customClass,
            bemClass
        ]"
        :style="[
            customStyle,
            {'--custom-scroll-max-width': $u.unit(maxWidth)},
            {'--custom-scroll-max-height': $u.unit(maxHeight)}
        ]"
        class="u-scroller"
    >
        <!-- 使用滚动条 -->
        <template v-if="!disableScroller && pageStatus !== 'empty'">
            <!-- 滚动区域 -->
            <scroll-view
                :enable-back-to-top="enableBackToTop"
                :enable-flex="enableFlex"
                :lower-threshold="lowerThreshold"
                :scroll-anchoring="scrollAnchoring"
                :scroll-left="scrollPosition"
                :scroll-top="scrollPosition"
                :scroll-with-animation="scrollWithAnimation"
                :scroll-x="direction === 'horizontal'"
                :scroll-y="direction === 'vertical'"
                :show-scrollbar="showScrollbar"
                :throttle="false"
                :upper-threshold="upperThreshold"
                class="context-scroll-view"
                @scroll="scrollHandler"
                @scrolltolower="scrolltolowerHandler"
                @scrolltoupper="scrolltoupperHandler"
            >
                <!-- 自定义加载区域 -->
                <view
                    v-if="enableRefresh"
                    :style="[
                        getLoadingBackgroundColor,
                        loadingStyle
                    ]"
                    class="loading"
                    @transitionend="transitionendHandler"
                >
                    <!-- 刷新状态 -->
                    <view
                        v-if="showRefreshing"
                        :style="[
                            {
                                opacity: moving / offset
                            }
                        ]"
                        class="loading-view"
                    >
                        <!-- 圆环 -->
                        <view
                            :class="[getRefreshState]"
                            :style="getMovingProgressStyle"
                            class="refreshing-circle"
                        />
                        <!-- //圆环 -->

                        <!-- 文本 -->
                        <view
                            v-if="direction === 'vertical'"
                            class="title"
                        >
                            <u-text
                                :text="getMovingText"
                                color="rgba(165, 165, 165)"
                            />
                        </view>
                        <!-- //文本 -->
                    </view>
                    <!-- //刷新状态 -->

                    <!-- 自定义插槽 -->
                    <view
                        v-if="!showRefreshing && $slots.refresh"
                        :style="[
                            {
                                opacity: moving / offset
                            }
                        ]"
                        class="custom-loading-slots"
                    >
                        <slot name="refresh" />
                    </view>
                    <!-- //自定义插槽 -->
                </view>
                <!-- //自定义加载区域 -->

                <!-- 滚动内盒 -->
                <view
                    :style="[
                        movingStyle,
                        getSpacing
                    ]"
                    class="context-scroll-inner-view"
                    @touchend="touchendHandler"
                    @touchmove="touchmoveHandler"
                    @touchstart="touchstartHandler"
                >
                    <!-- 页眉 -->
                    <view
                        v-if="$slots.pageHeader"
                        class="page-header"
                    >
                        <slot name="pageHeader" />
                    </view>
                    <!-- //页眉 -->

                    <slot />

                    <!-- 页脚 -->
                    <view class="page-footer">
                        <!-- 页脚状态 -->
                        <view
                            v-if="(pageStatus === 'loading' && !useCustomPageLoading || pageStatus === 'noMore' && !useCustomPageNoMore) && refreshing !== 2"
                            :style="[
                                {
                                    opacity: 1 - moving / offset
                                }
                            ]"
                            class="page-footer-text"
                        >
                            <u-text :text="getPageFooterText" />
                        </view>
                        <!-- //页脚状态 -->

                        <!-- 自定义数据加载中插槽 -->
                        <view
                            v-if="useCustomPageLoading && $slots.pageLoading && pageStatus === 'loading'"
                            class="custom-page-loading-slots"
                        >
                            <slot name="pageLoading" />
                        </view>
                        <!-- //自定义数据加载中插槽 -->

                        <!-- 自定义暂无更多数据插槽 -->
                        <view
                            v-if="useCustomPageNoMore && $slots.pageNoMore && pageStatus === 'noMore'"
                            class="custom-page-no-more-slots"
                        >
                            <slot name="pageNoMore" />
                        </view>
                        <!-- //自定义暂无更多数据插槽 -->

                        <!-- 自定义默认状态插槽 -->
                        <view
                            v-if="useCustomPageNone && $slots.pageNone && pageStatus === 'none'"
                            class="custom-page-none-slots"
                        >
                            <slot name="pageNone" />
                        </view>
                        <!-- //自定义默认状态插槽 -->
                    </view>
                    <!-- //页脚 -->
                </view>
                <!-- //滚动内盒 -->
            </scroll-view>
            <!-- //滚动区域 -->
        </template>
        <!-- //使用滚动条 -->

        <!-- 禁止使用滚动条 -->
        <template v-else-if="pageStatus !== 'empty'">
            <view class="context-scroll-view">
                <slot />
            </view>
        </template>
        <!-- //禁止使用滚动条 -->

        <!-- 空数据 -->
        <template v-else>
            <view class="empty">
                <!-- 空数据信息 -->
                <view
                    v-if="!useCustomPageEmpty"
                    class="empty-view"
                >
                    <!-- 图片 -->
                    <view class="image">
                        <u-image
                            :fade="false"
                            :show-loading="false"
                            :src="`/static/images/empty.png`"
                        />
                    </view>
                    <!-- //图片 -->

                    <!-- 文本 -->
                    <view class="text">
                        <u-text :text="getPageFooterText" />
                    </view>
                    <!-- //文本 -->
                </view>
                <!-- //空数据信息 -->

                <!-- 空数据自定义插槽 -->
                <view
                    v-if="$slots.pageEmpty && useCustomPageEmpty"
                    class="custom-empty-slots"
                >
                    <slot name="pageEmpty" />
                </view>
                <!-- //空数据自定义插槽 -->
            </view>
        </template>
        <!-- //空数据 -->
    </view>
    <!-- //滚动组件 -->
</template>

<style lang="scss" scoped>
    .u-scroller
    {
        overflow: hidden;
        width: 100%;
        height: 100%;
        max-height: var(--custom-scroll-max-height, "auto");

        // 滚动区域
        .context-scroll-view
        {
            /*   解决警告：Unable to preventDefault inside passive event listener due to target being treated as passive.
                 auto：不限制任何触摸行为，浏览器会根据上下文自动处理触摸事件。
                 none：禁用所有默认的触摸行为（如平移、缩放、旋转）。
                 pan-x：只允许水平方向（X 轴）的平移手势。
                 pan-y：只允许垂直方向（Y 轴）的平移手势。
                 pan-x pan-y 或 pan-y pan-x：允许在两个方向（X 和 Y 轴）上的平移手势。
                 pinch-zoom：允许双指缩放手势。
                 manipulation：只允许平移和缩放手势，禁止旋转手势。
                 pan-left：只允许向左平移的手势。
                 pan-right：只允许向右平移的手势。
                 pan-up：只允许向上平移的手势。
                 pan-down：只允许向下平移的手势。
            */
            max-width: var(--custom-scroll-max-width, "auto");
            max-height: var(--custom-scroll-max-height, "auto");
            touch-action: none;

            // 自定义加载区域
            .loading
            {
                position: absolute;
                overflow: hidden;
                pointer-events: none;
                box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12) inset;

                // 加载区域
                .loading-view
                {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    height: 100%;
                    opacity: 0;

                    // 圆环
                    .refreshing-circle
                    {
                        position: relative;
                        width: 12px;
                        height: 12px;
                        border-width: 2px;
                        border-style: solid;
                        border-radius: 100%;

                        // 加载中
                        &.refresh
                        {
                            animation: circle infinite 0.75s linear;
                        }

                        // 转转转动画
                        @keyframes circle
                        {
                            0%
                            {
                                transform: rotate(0);
                            }
                            100%
                            {
                                transform: rotate(360deg);
                            }
                        }
                    }

                    // 标题
                    .title
                    {
                        margin-left: 4px;
                    }
                }

                // 自定义插槽
                .custom-loading-slots
                {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    height: 100%;
                }
            }

            // 滚动内盒
            .context-scroll-inner-view
            {
                // 页脚
                .page-footer
                {
                    display: flex;
                    align-items: center;
                    justify-content: center;

                    // 页脚状态
                    .page-footer-text
                    {
                        padding: 10px 0;
                    }
                }
            }
        }

        // 空数据
        .empty
        {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 100%;
            height: 100%;

            // 空数据区域
            .empty-view
            {
                display: flex;
                align-items: center;
                flex-direction: column;
                justify-content: center;

                // 图片
                .image
                {
                    width: 160px;
                    height: 160px;
                }
            }
        }

        // 横向滚动
        &-horizontal
        {
            // 滚动区域
            .context-scroll-view
            {
                width: 100%;
                white-space: nowrap;

                // 自定义加载区域
                .loading
                {
                    top: 0;
                    bottom: 0;
                    left: 0;
                    width: 0;
                }
            }
        }

        // 纵向滚动
        &-vertical
        {
            // 滚动区域
            .context-scroll-view
            {
                position: relative;
                height: 100%;

                // 自定义加载区域
                .loading
                {
                    top: 0;
                    right: 0;
                    left: 0;
                    height: 0;
                }
            }
        }
    }

    // 隐藏默认滚动条
    ::-webkit-scrollbar
    {
        display: none !important;
        width: 0 !important;
        height: 0 !important;
        background: transparent;
        -webkit-appearance: none;
    }
</style>